import time
from decimal import Decimal

from django.http import JsonResponse, HttpResponse
from django.shortcuts import render, redirect
from django.views.generic import View
from django_redis import get_redis_connection
from django.db import transaction

from apps.goods.models import Goods, Youhuiquan
from apps.order.models import OrderInfo, OrderGoods
from apps.user.models import Address
from utils.mixin import LoginRequiredMixin


class OrderPlaceView(LoginRequiredMixin, View):
    ''' 去结算请求，渲染下订单页面，只需要前端form表单携带需要下订单的商品id即可 '''

    def post(self, request):
        # 通过商品id查询该商品信息，以及redis购物车中对应的商品数量，计算出小计，合计等信息
        sku_ids = request.POST.getlist('sku_id')
        if not sku_ids:
            return redirect('')
        try:
            redis_conn = get_redis_connection('default')
            redis_key = 'cart_%d' % request.user.id
            skus = []
            total_price = Decimal('0.00')
            total_count = 0
            for sku_id in sku_ids:
                sku = Goods.objects.get(id=sku_id)
                count = int(redis_conn.hget(redis_key, sku.id))
                amount = Decimal(sku.price) * count
                sku.count = count
                sku.amount = amount
                total_price += amount
                total_count += count
                skus.append(sku)

            user_id = request.user.id
            quan = Youhuiquan.objects.filter(owner=user_id).values('price')
            if not quan:
                yhq = 0
            else:
                for item in quan:
                    yhq = item['price']
            # 查询用户的收货地址
            addr = Address.objects.filter(user=request.user)

        except Exception as e:
            return redirect('/')
        sku_ids = ','.join(sku_ids)  # 1,3
        context = {"total_price": total_price, "total_count": total_count, "skus": skus, "addrs": addr,
                   "sku_ids": sku_ids, 'quan': yhq}
        return render(request, 'place_order.html', context)


class OrderDirView(LoginRequiredMixin, View):
    def post(self, request):
        user_id = request.user.id
        sku_id = request.POST.get('good_id')
        total_count = int(request.POST.get('num_show'))
        print(total_count, type(total_count))
        # total_price = Decimal('0.00')
        sku = Goods.objects.get(id=sku_id)
        total_price = sku.price * total_count
        quan = Youhuiquan.objects.filter(owner=user_id).values('price')
        sku.count = total_count
        sku.amount = total_price
        if not quan:
            yhq = 0

        else:
            for item in quan:
                yhq = item['price']

        # 查询用户的收货地址
        addr = Address.objects.filter(user=request.user)

        if sku.stock < total_count:
            return HttpResponse('<script>alert("库存不足"); history.back(-1);</script>')
            # return render(request,'detail.html', {'res': '库存不足'})
        else:

            redis_conn = get_redis_connection("default")
            redis_conn.hset('cart_%d' % user_id, sku_id, total_count)
            cart_len = redis_conn.hlen(f'cart_{user_id}')

            # return JsonResponse({"res": 1, "msg": "加入购物车成功", "cart_len": cart_len})
            context = {"total_price": total_price, "total_count": total_count, "skus": [sku], "addrs": addr,
                       "sku_ids": sku_id, 'quan': yhq, 'cart_len': cart_len, 'stock': sku.stock}
            return render(request, 'place_order.html', context)


class OrderCommitView(View):
    '''提交订单：ajax请求，携带各个商品id，收货地址id，支付方式'''

    @transaction.atomic  # 启用事务
    def post(self, request):

        if not request.user.is_authenticated:
            return JsonResponse({"res": 0, "msg": "登录超时，请重新登录"})
        sku_ids = request.POST.get('sku_ids')  # 1,3
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        quan_method = request.POST.get('quan_method')

        if not all([sku_ids, addr_id, pay_method]):
            return JsonResponse({"res": 0, "msg": "请填写地址"})
        try:
            address = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            return JsonResponse({"res": 0, "msg": "收货地址错误"})

        sid = transaction.savepoint()  # 设置事务保存点

        # 创建订单
        try:
            userid = request.user.id
            if quan_method == '2':
                Youhuiquan.objects.filter(owner=userid).delete()
            order_id = time.strftime("%Y%m%d%H%M%S", time.localtime()) + str(userid)  # 订单id：202208221117351(年月日时分秒用户id)
            order_info = OrderInfo.objects.create(order_id=order_id, addr=address, user=request.user,
                                                  pay_methods=pay_method, total_count=0, total_price=0, transit_price=0)

            # 创建订单商品信息
            sku_ids = sku_ids.split(',')
            redis_conn = get_redis_connection("default")
            total_price = Decimal('0.00')
            total_count = 0
            for sku_id in sku_ids:
                for i in range(3):
                    try:
                        sku = Goods.objects.get(id=sku_id)
                    except Goods.DoesNotExist:
                        transaction.savepoint_rollback(sid)
                        return JsonResponse({"res": 0, "msg": "没有相关商品"})

                    count = int(redis_conn.hget('cart_%d' % userid, sku_id))
                    amount = Decimal(sku.price) * count
                    total_count += count
                    total_price = amount + total_price
                    if sku.stock < count:
                        transaction.savepoint_rollback(sid)
                        return JsonResponse({"res": 0, "msg": "商品库存不足"})

                    # 乐观锁解决并发问题
                    origin_stock = sku.stock
                    new_stock = origin_stock - count
                    new_sales = sku.sales + count
                    if new_stock <= 0:
                        res = Goods.objects.filter(id=sku_id, stock=origin_stock).update(stock=new_stock,
                                                                                     sales=new_sales, state=0)
                    else:
                        res = Goods.objects.filter(id=sku_id, stock=origin_stock).update(stock=new_stock,
                                                                                         sales=new_sales)
                    if res == 0:
                        if i == 2:
                            transaction.savepoint_rollback(sid)
                            return JsonResponse({"res": 0, "msg": "下单失败"})
                        continue
                    OrderGoods.objects.create(order_info=order_info, goods_sku=sku, count=count, price=amount,
                                              comment='')
                    break

            # 更新订单中商品总数量和总价格
            order_info.total_count = total_count
            order_info.total_price = total_price
            order_info.save()

        except Exception as e:
            print(e)
            transaction.savepoint_rollback(sid)
            return JsonResponse({"res": 0, "msg": "下单失败"})

        transaction.savepoint_commit(sid)  # 提交事务
        # 清除购物车中已购买的商品数量
        redis_conn.hdel('cart_%d' % userid, *sku_ids)
        return JsonResponse({"res": 1, "msg": "提交订单成功"})


class OrderCommentView(LoginRequiredMixin, View):

    def get(self, request, order_id):

        if not order_id:
            return redirect("/user/order/1/")
        try:
            order = OrderInfo.objects.get(order_id=order_id, user=request.user)
        except OrderInfo.DoesNotExist:
            return redirect("/user/order/1/")
        order.status_name = OrderInfo.ORDER_STATUS[order.status]
        # 获取订单商品信息
        order_skus = OrderGoods.objects.filter(order_info=order)
        order.order_skus = order_skus

        return render(request, 'order_comment.html', {"order": order})

    def post(self, request, order_id):
        """处理评论内容"""
        user = request.user
        # 校验数据
        if not order_id:
            return redirect("/user/order/", kwargs={"page": 1})
        try:
            order = OrderInfo.objects.get(order_id=order_id, user=user)
        except OrderInfo.DoesNotExist:
            return redirect("/user/order/", kwargs={"page": 1})

        # 获取评论条数
        total_count = request.POST.get("total_count")
        total_count = int(total_count)

        # 循环获取订单中商品的评论内容
        for i in range(1, total_count + 1):
            # 获取评论的商品的id
            sku_id = request.POST.get("sku_%d" % i)  # sku_1 sku_2
            # 获取评论的商品的内容
            content = request.POST.get('content_%d' % i, '')  # cotent_1 content_2 content_3
            try:
                order_goods = OrderGoods.objects.get(order_info=order, goods_sku=sku_id)
            except OrderGoods.DoesNotExist:
                continue

            order_goods.comment = content
            order_goods.save()

        order.status = 2
        order.save()


        return redirect("/user/order/1/")
